/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package flightlifter;

import java.nio.FloatBuffer;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;

/**
 *
 * @author Matt
 */
public class Draw {

    public static void box() {
        GL11.glLineWidth(1.5f);
        GL11.glBegin(GL11.GL_LINE_LOOP);                    // Drawing Using Triangles

        GL11.glVertex3f(-1f, -1f, -1f);
        GL11.glVertex3f(-1f, 1f, -1f);
        GL11.glVertex3f(1f, 1f, -1f);
        GL11.glVertex3f(1f, -1f, -1f);
        GL11.glEnd();

        GL11.glBegin(GL11.GL_LINE_LOOP);                    // Drawing Using Triangles

        GL11.glVertex3f(-1f, -1f, 1f);
        GL11.glVertex3f(-1f, 1f, 1f);
        GL11.glVertex3f(1f, 1f, 1f);
        GL11.glVertex3f(1f, -1f, 1f);
        GL11.glEnd();

        GL11.glBegin(GL11.GL_LINES);                    // Drawing Using Triangles

        GL11.glVertex3f(-1f, -1f, -1f);
        GL11.glVertex3f(-1f, -1f, 1f);

        GL11.glVertex3f(1f, 1f, -1f);
        GL11.glVertex3f(1f, 1f, 1f);

        GL11.glVertex3f(-1f, 1f, -1f);
        GL11.glVertex3f(-1f, 1f, 1f);

        GL11.glVertex3f(1f, -1f, -1f);
        GL11.glVertex3f(1f, -1f, 1f);

        GL11.glEnd();

    }

    public static void solidBox() {

        GL11.glBegin(GL11.GL_QUADS);                    // Drawing Using Triangles
        GL11.glNormal3f(0, 0, 1);
        GL11.glVertex3f(-1f, -1f, -1f);
        GL11.glVertex3f(-1f, 1f, -1f);
        GL11.glVertex3f(1f, 1f, -1f);
        GL11.glVertex3f(1f, -1f, -1f);
        GL11.glEnd();

        GL11.glBegin(GL11.GL_QUADS);                    // Drawing Using Triangles
        GL11.glNormal3f(0, 0, 1);
        GL11.glVertex3f(-1f, -1f, 1f);
        GL11.glVertex3f(-1f, 1f, 1f);
        GL11.glVertex3f(1f, 1f, 1f);
        GL11.glVertex3f(1f, -1f, 1f);
        GL11.glEnd();



    }

    public static void rect(float x, float y, float width, float height){

        GL11.glBegin(GL11.GL_LINE_LOOP);
        GL11.glNormal3f(0, 0, 1);
        GL11.glVertex3f(x,y, 0f);
        GL11.glVertex3f(x + width,y, 0f);
        GL11.glVertex3f(x+width,y+height, 0f);
        GL11.glVertex3f(x, y + height, 0f);
        GL11.glEnd();

    }
    
    public static void fillRect(float x, float y, float width, float height){

        GL11.glBindTexture(GL11.GL_TEXTURE_2D,0);
        GL11.glBegin(GL11.GL_QUADS);
        GL11.glNormal3f(0, 0, 1);
        GL11.glVertex3f(x,y, 0f);
        GL11.glVertex3f(x + width,y, 0f);
        GL11.glVertex3f(x+width,y+height, 0f);
        GL11.glVertex3f(x, y + height, 0f);
        GL11.glEnd();

    }

    public static void gridRect(float sz) {

        GL11.glPushMatrix();
        GL11.glTranslatef(-sz / 2, -sz / 2, 0);

        GL11.glLineWidth(1.f);

        GL11.glBegin(GL11.GL_LINES);                    // Drawing Using Triangles
        for (int i = 0; i < sz; i++) {

            if (i % 10 == 0){
                GL11.glColor3f(.0f, 0f, 0f);
            } else if (i % 5 == 0){
                GL11.glColor3f(.1f, .1f, .1f);
            }
            else  {
                GL11.glColor3f(.25f, .25f, .25f);
   
            }

            GL11.glVertex3f(0, i, 0.0f);
            GL11.glVertex3f(sz, i, 0.0f);

            GL11.glVertex3f(i, 0, 0.0f);
            GL11.glVertex3f(i, sz, 0.0f);
        }
        GL11.glEnd();

        GL11.glColor3f(.0f, .0f, .0f);

        GL11.glLineWidth(2.f);
        GL11.glBegin(GL11.GL_LINE_LOOP);                    // Drawing Using Triangles

        GL11.glVertex3f(0, 0, 0.0f);
        GL11.glVertex3f(0, sz, 0.0f);
        GL11.glVertex3f(sz, sz, 0.0f);
        GL11.glVertex3f(sz, 0, 0.0f);
        GL11.glEnd();

        GL11.glPopMatrix();

    }
    public static void renderPlane(float size, int segments) {
        renderPlane(size,size,segments,segments);
    }
   public static void renderPlane(float length, float height, int length_segments, int height_segments) {
        renderPlane(length, height, length_segments, height_segments, 1, 1);
    }
    public static void renderPlane(float length, float height, int length_segments, int height_segments, float tilefactorU, float tilefactorV) {
    	float xpos = - length/2f;
    	float ypos = - height/2f;
    	float segsizeL = length/(float)length_segments;
    	float segsizeH = height/(float)height_segments;
        float maxDimension = (length > height)? length : height;
    	float uvsegsizeL = (length/maxDimension) / (float)length_segments;
    	float uvsegsizeH = (height/maxDimension) / (float)height_segments;
    	GL11.glBegin(GL11.GL_QUADS); {
    		GL11.glNormal3f(0f, 0f, 1f);   // plane is facing up the Z axis
    		for (int x=0; x < length_segments; x++, xpos+=segsizeL) {
    			for (int y=0; y < height_segments; y++, ypos+=segsizeH) {
    				// bottom left
    				GL11.glTexCoord2f((x*uvsegsizeL)*tilefactorU, (y*uvsegsizeH)*tilefactorV);
    				GL11.glVertex3f( xpos, ypos, 0f);
    				// bottom rite
    				GL11.glTexCoord2f(((x*uvsegsizeL)+uvsegsizeL)*tilefactorU, (y*uvsegsizeH)*tilefactorV);
    				GL11.glVertex3f( xpos+segsizeL, ypos,  0f);
    				// top rite
    				GL11.glTexCoord2f(((x*uvsegsizeL)+uvsegsizeL)*tilefactorU, ((y*uvsegsizeH)+uvsegsizeH)*tilefactorV);
    				GL11.glVertex3f( xpos+segsizeL,  ypos+segsizeH, 0f);
    				// top left
    				GL11.glTexCoord2f((x*uvsegsizeL)*tilefactorU, ((y*uvsegsizeH)+uvsegsizeH)*tilefactorV);
    				GL11.glVertex3f( xpos,  ypos+segsizeH, 0f);
    			}
    			ypos = - height/2f; // reset column position
    		}
    	}
    	GL11.glEnd();
    }

        public static void renderCube(float size, int segments) {
    	float halfsize = size/2f;
    	GL11.glPushMatrix();
    	{
    		GL11.glPushMatrix();
    		{
    			GL11.glTranslatef(0,0,halfsize);
    			renderPlane(size,segments);// front
    		}
    		GL11.glPopMatrix();
    		GL11.glPushMatrix();
    		{
    			GL11.glRotatef(90,0,1,0);
    			GL11.glTranslatef(0,0,halfsize);
    			renderPlane(size,segments);// right
    		}
    		GL11.glPopMatrix();
    		GL11.glPushMatrix();
    		{
    			GL11.glRotatef(180,0,1,0);
    			GL11.glTranslatef(0,0,halfsize);
    			renderPlane(size,segments);// back
    		}
    		GL11.glPopMatrix();
    		GL11.glPushMatrix();
    		{
    			GL11.glRotatef(270,0,1,0);
    			GL11.glTranslatef(0,0,halfsize);
    			renderPlane(size,segments);// left
    		}
    		GL11.glPopMatrix();
    		GL11.glPushMatrix();
    		{
    			GL11.glRotatef(90,1,0,0);
    			GL11.glTranslatef(0,0,halfsize);
    			renderPlane(size,segments);// bottom
    		}
    		GL11.glPopMatrix();
    		GL11.glPushMatrix();
    		{
    			GL11.glRotatef(-90,1,0,0);
    			GL11.glTranslatef(0,0,halfsize);
    			renderPlane(size,segments);// top
    		}
    		GL11.glPopMatrix();
    	}
    	GL11.glPopMatrix();
    }




    public static void rect(float size, float textureScale) {

        GL11.glBegin(GL11.GL_QUADS);                    // Drawing Using Triangles
        
        float sz = size / 2;

        GL11.glNormal3f(0, 1.f,0);
        GL11.glTexCoord2f(0, 0);
        GL11.glVertex3f(-sz,0, -sz);

        GL11.glNormal3f(0, 1.f,0);
        GL11.glTexCoord2f(0, textureScale);
        GL11.glVertex3f(-sz,0, sz);

        GL11.glNormal3f(0, 1.f,0);
        GL11.glTexCoord2f(textureScale, textureScale);
        GL11.glVertex3f(sz,0, sz);

        GL11.glNormal3f(0, 1.f,0);
        GL11.glTexCoord2f(textureScale, 0);
        GL11.glVertex3f(sz,0, -sz);

        GL11.glEnd();

/*
        GL11.glColor3f(0, 0, 0);

        GL11.glBegin(GL11.GL_LINE_STRIP);                    // Drawing Using Triangles
        GL11.glVertex3f(-sz, -sz, 0.0f);
        GL11.glVertex3f(-sz, sz, 0.0f);
        GL11.glVertex3f(sz, sz, 0.0f);
        GL11.glVertex3f(sz, -sz, 0.0f);
        GL11.glVertex3f(-sz, -sz, 0.0f);
        GL11.glEnd();
*/


    }
    final int patchdata[][] = {
        /* rim */
        {102, 103, 104, 105, 4, 5, 6, 7, 8, 9, 10, 11,
            12, 13, 14, 15},
        /* body */
        {12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
            24, 25, 26, 27},
        {24, 25, 26, 27, 29, 30, 31, 32, 33, 34, 35, 36,
            37, 38, 39, 40},
        /* lid */
        {96, 96, 96, 96, 97, 98, 99, 100, 101, 101, 101,
            101, 0, 1, 2, 3,},
        {0, 1, 2, 3, 106, 107, 108, 109, 110, 111, 112,
            113, 114, 115, 116, 117},
        /* bottom */
        {118, 118, 118, 118, 124, 122, 119, 121, 123, 126,
            125, 120, 40, 39, 38, 37},
        /* handle */
        {41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
            53, 54, 55, 56},
        {53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
            28, 65, 66, 67},
        /* spout */
        {68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
            80, 81, 82, 83},
        {80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
            92, 93, 94, 95}
    };
    /** Used to make the teapot. **/
    final float cpdata[][] = {
        {0.2f, 0, 2.7f}, {0.2f, -0.112f, 2.7f}, {0.112f, -0.2f, 2.7f}, {0,
            -0.2f, 2.7f}, {1.3375f, 0, 2.53125f}, {1.3375f, -0.749f, 2.53125f},
        {0.749f, -1.3375f, 2.53125f}, {0, -1.3375f, 2.53125f}, {1.4375f,
            0, 2.53125f}, {1.4375f, -0.805f, 2.53125f}, {0.805f, -1.4375f,
            2.53125f}, {0, -1.4375f, 2.53125f}, {1.5f, 0, 2.4f}, {1.5f, -0.84f,
            2.4f}, {0.84f, -1.5f, 2.4f}, {0, -1.5f, 2.4f}, {1.75f, 0, 1.875f},
        {1.75f, -0.98f, 1.875f}, {0.98f, -1.75f, 1.875f}, {0, -1.75f,
            1.875f}, {2f, 0, 1.35f}, {2f, -1.12f, 1.35f}, {1.12f, -2f, 1.35f},
        {0, -2f, 1.35f}, {2f, 0, 0.9f}, {2f, -1.12f, 0.9f}, {1.12f, -2f,
            0.9f}, {0, -2f, 0.9f}, {-2f, 0, 0.9f}, {2f, 0, 0.45f}, {2f, -1.12f,
            0.45f}, {1.12f, -2f, 0.45f}, {0, -2f, 0.45f}, {1.5f, 0, 0.225f},
        {1.5f, -0.84f, 0.225f}, {0.84f, -1.5f, 0.225f}, {0, -1.5f, 0.225f},
        {1.5f, 0, 0.15f}, {1.5f, -0.84f, 0.15f}, {0.84f, -1.5f, 0.15f}, {0,
            -1.5f, 0.15f}, {-1.6f, 0, 2.025f}, {-1.6f, -0.3f, 2.025f}, {-1.5f,
            -0.3f, 2.25f}, {-1.5f, 0, 2.25f}, {-2.3f, 0, 2.025f}, {-2.3f, -0.3f,
            2.025f}, {-2.5f, -0.3f, 2.25f}, {-2.5f, 0, 2.25f}, {-2.7f, 0,
            2.025f}, {-2.7f, -0.3f, 2.025f}, {-3f, -0.3f, 2.25f}, {-3f, 0,
            2.25f}, {-2.7f, 0, 1.8f}, {-2.7f, -0.3f, 1.8f}, {-3f, -0.3f, 1.8f},
        {-3f, 0, 1.8f}, {-2.7f, 0, 1.575f}, {-2.7f, -0.3f, 1.575f}, {-3f,
            -0.3f, 1.35f}, {-3f, 0, 1.35f}, {-2.5f, 0, 1.125f}, {-2.5f, -0.3f,
            1.125f}, {-2.65f, -0.3f, 0.9375f}, {-2.65f, 0, 0.9375f}, {-2f,
            -0.3f, 0.9f}, {-1.9f, -0.3f, 0.6f}, {-1.9f, 0, 0.6f}, {1.7f, 0,
            1.425f}, {1.7f, -0.66f, 1.425f}, {1.7f, -0.66f, 0.6f}, {1.7f, 0,
            0.6f}, {2.6f, 0, 1.425f}, {2.6f, -0.66f, 1.425f}, {3.1f, -0.66f,
            0.825f}, {3.1f, 0, 0.825f}, {2.3f, 0, 2.1f}, {2.3f, -0.25f, 2.1f},
        {2.4f, -0.25f, 2.025f}, {2.4f, 0, 2.025f}, {2.7f, 0, 2.4f}, {2.7f,
            -0.25f, 2.4f}, {3.3f, -0.25f, 2.4f}, {3.3f, 0, 2.4f}, {2.8f, 0,
            2.475f}, {2.8f, -0.25f, 2.475f}, {3.525f, -0.25f, 2.49375f},
        {3.525f, 0, 2.49375f}, {2.9f, 0, 2.475f}, {2.9f, -0.15f, 2.475f},
        {3.45f, -0.15f, 2.5125f}, {3.45f, 0, 2.5125f}, {2.8f, 0, 2.4f},
        {2.8f, -0.15f, 2.4f}, {3.2f, -0.15f, 2.4f}, {3.2f, 0, 2.4f}, {0, 0,
            3.15f}, {0.8f, 0, 3.15f}, {0.8f, -0.45f, 3.15f}, {0.45f, -0.8f,
            3.15f}, {0, -0.8f, 3.15f}, {0, 0, 2.85f}, {1.4f, 0, 2.4f}, {1.4f,
            -0.784f, 2.4f}, {0.784f, -1.4f, 2.4f}, {0, -1.4f, 2.4f}, {0.4f, 0,
            2.55f}, {0.4f, -0.224f, 2.55f}, {0.224f, -0.4f, 2.55f}, {0, -0.4f,
            2.55f}, {1.3f, 0, 2.55f}, {1.3f, -0.728f, 2.55f}, {0.728f, -1.3f,
            2.55f}, {0, -1.3f, 2.55f}, {1.3f, 0, 2.4f}, {1.3f, -0.728f, 2.4f},
        {0.728f, -1.3f, 2.4f}, {0, -1.3f, 2.4f}, {0, 0, 0}, {1.425f,
            -0.798f, 0}, {1.5f, 0, 0.075f}, {1.425f, 0, 0}, {0.798f, -1.425f,
            0}, {0, -1.5f, 0.075f}, {0, -1.425f, 0}, {1.5f, -0.84f, 0.075f},
        {0.84f, -1.5f, 0.075f}
    };

    public void fastSolidTeapot(int grid, float scale) {
        float p[][][] = new float[4][4][3];
        float q[][][] = new float[4][4][3];
        float r[][][] = new float[4][4][3];
        float s[][][] = new float[4][4][3];
        int i, j, k, l;
        final FloatBuffer buffer = BufferUtils.createFloatBuffer(4 * 4 * 3);

        GL11.glEnable(GL11.GL_AUTO_NORMAL);
        GL11.glEnable(GL11.GL_MAP2_VERTEX_3);
        GL11.glRotatef(270.0f, 1.0f, 0.0f, 0.0f);
        GL11.glScalef(0.5f * scale, 0.5f * scale, 0.5f * scale);
        GL11.glTranslatef(0.0f, 0.0f, -1.5f);

        for (i = 0; i < 10; i++) {
            for (j = 0; j < 4; j++) {
                for (k = 0; k < 4; k++) {
                    for (l = 0; l < 3; l++) {
                        p[j][k][l] = cpdata[patchdata[i][j * 4 + k]][l];
                        q[j][k][l] = cpdata[patchdata[i][j * 4 + (3 - k)]][l];

                        if (l == 1) {
                            q[j][k][l] *= -1.0;
                        }

                        if (i < 6) {
                            r[j][k][l] = cpdata[patchdata[i][j * 4 + (3 - k)]][l];

                            if (l == 0) {
                                r[j][k][l] *= -1.0;
                            }

                            s[j][k][l] = cpdata[patchdata[i][j * 4 + k]][l];

                            if (l == 0) {
                                s[j][k][l] *= -1.0;
                            }

                            if (l == 1) {
                                s[j][k][l] *= -1.0;
                            }
                        }
                    }
                }
            }

            putIntoBuffer(buffer, p);
            GL11.glMap2f(GL11.GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4, buffer);
            GL11.glMapGrid2f(grid, 0.0f, 1.0f, grid, 0.0f, 1.0f);
            GL11.glEvalMesh2(GL11.GL_FILL, 0, grid, 0, grid);
            putIntoBuffer(buffer, q);
            GL11.glMap2f(GL11.GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4, buffer);
            GL11.glEvalMesh2(GL11.GL_FILL, 0, grid, 0, grid);

            if (i < 6) {
                putIntoBuffer(buffer, r);
                GL11.glMap2f(GL11.GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4, buffer);
                GL11.glEvalMesh2(GL11.GL_FILL, 0, grid, 0, grid);
                putIntoBuffer(buffer, s);
                GL11.glMap2f(GL11.GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4, buffer);
                GL11.glEvalMesh2(GL11.GL_FILL, 0, grid, 0, grid);
            }
        }
    }

    public void putIntoBuffer(FloatBuffer buffer, float array[][][]) {
        buffer.clear();

        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                for (int k = 0; k < 3; k++) {
                    buffer.put(array[i][j][k]);
                }
            }
        }

        buffer.rewind();
    }
}
